/**
 * Created by PanJiaChen on 16/11/18.
 */
import { isObject } from './validate'
/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @param {number} datetype 0-不转换类型  1-周 2-月 3-季度
 * @returns {string}
 */
export function parseTime(time, cFormat, datetype = 0) {
  if (arguments.length === 0) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  let endweekdate

  if (typeof time === 'undefined' || time === null || time === 'null') {
    return ''
  } else if (typeof time === 'object') {
    date = time
  } else {
    if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
      time = parseInt(time)
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000
    }
    const u = navigator.userAgent
    const isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
    const isSafari = /Safari/.test(u) && !/Chrome/.test(u)
    if (isiOS || isSafari) {
      if (time.includes('T')) {
        date = new Date(time)
      } else {
        date = new Date(time.replace(/-/g, '/'))
      }
    } else {
      date = new Date(time)
    }

    if (datetype === 1) {
      endweekdate =
        new Date(date.getTime() + 6 * 24 * 3600 * 1000) > new Date(new Date().setHours(0)).getTime()
          ? new Date(new Date().getTime() - 24 * 3600 * 1000)
          : new Date(date.getTime() + 6 * 24 * 3600 * 1000)
    }
  }
  const time_str = formatDate(date, format)
  if (datetype === 1) {
    const time_str_end = formatDate(endweekdate, format)
    return `${time_str}~${time_str_end}`
  } else if (datetype === 3) {
    const quarterly = {
      Q1: [1, 2, 3],
      Q2: [4, 5, 6],
      Q3: [7, 8, 9],
      Q4: [10, 11, 12]
    }
    const month = date.getMonth() + 1
    let quarterlystr = ''
    Object.keys(quarterly).map(key => {
      if (quarterly[key].includes(month)) {
        quarterlystr = key
      }
    })
    return `${date.getFullYear()}-${quarterlystr}`
  } else {
    return time_str
  }
}

export function parseTimeByUTC(time) {
  const date = new Date(time)
  const year = date.getUTCFullYear()
  const month = ('0' + (date.getUTCMonth() + 1)).slice(-2)
  const day = ('0' + date.getUTCDate()).slice(-2)
  const hours = ('0' + date.getUTCHours()).slice(-2)
  const minutes = ('0' + date.getUTCMinutes()).slice(-2)
  const seconds = ('0' + date.getUTCSeconds()).slice(-2)
  // 组合成最终格式化后的字符串
  const formattedTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  return formattedTime
}

function formatDate(date, format) {
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime(time, option) {
  if (('' + time).length === 10) {
    time = parseInt(time) * 1000
  } else {
    time = +time
  }
  const d = new Date(time)
  const now = Date.now()

  const diff = (now - d) / 1000

  if (diff < 30) {
    return '刚刚'
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前'
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前'
  } else if (diff < 3600 * 24 * 2) {
    return '1天前'
  }
  if (option) {
    return parseTime(time, option)
  } else {
    return d.getMonth() + 1 + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分'
  }
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function getQueryObject(url) {
  url = url == null ? window.location.href : url
  const search = url.substring(url.lastIndexOf('?') + 1)
  const obj = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}

/**
 * @param {string} input value
 * @returns {number} output value
 */
export function byteLength(str) {
  // returns the byte length of an utf8 string
  let s = str.length
  for (var i = str.length - 1; i >= 0; i--) {
    const code = str.charCodeAt(i)
    if (code > 0x7f && code <= 0x7ff) s++
    else if (code > 0x7ff && code <= 0xffff) s += 2
    if (code >= 0xdc00 && code <= 0xdfff) i--
  }
  return s
}

/**
 * @param {Array} actual
 * @returns {Array}
 */
export function cleanArray(actual) {
  const newArray = []
  for (let i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i])
    }
  }
  return newArray
}

/**
 * @param {Object} json
 * @returns {Array}
 */
export function param(json) {
  if (!json) return ''
  return cleanArray(
    Object.keys(json).map(key => {
      if (json[key] === undefined) return ''
      return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
    })
  ).join('&')
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj(url) {
  const search = url.split('?')[1]
  if (!search) {
    return {}
  }
  return JSON.parse(
    '{"' +
      decodeURIComponent(search)
        .replace(/"/g, '\\"')
        .replace(/&/g, '","')
        .replace(/=/g, '":"')
        .replace(/\+/g, ' ') +
      '"}'
  )
}

/**
 * @param {string} val
 * @returns {string}
 */
export function html2Text(val) {
  const div = document.createElement('div')
  div.innerHTML = val
  return div.textContent || div.innerText
}

/**
 * Merges two objects, giving the last one precedence
 * @param {Object} target
 * @param {(Object|Array)} source
 * @returns {Object}
 */
export function objectMerge(target, source) {
  if (typeof target !== 'object') {
    target = {}
  }
  if (Array.isArray(source)) {
    return source.slice()
  }
  Object.keys(source).forEach(property => {
    const sourceProperty = source[property]
    if (typeof sourceProperty === 'object') {
      target[property] = objectMerge(target[property], sourceProperty)
    } else {
      target[property] = sourceProperty
    }
  })
  return target
}

/**
 * @param {HTMLElement} element
 * @param {string} className
 */
export function toggleClass(element, className) {
  if (!element || !className) {
    return
  }
  let classString = element.className
  const nameIndex = classString.indexOf(className)
  if (nameIndex === -1) {
    classString += '' + className
  } else {
    classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length)
  }
  element.className = classString
}

/**
 * @param {string} type
 * @returns {Date}
 */
export function getTime(type) {
  if (type === 'start') {
    return new Date().getTime() - 3600 * 1000 * 24 * 90
  } else {
    return new Date(new Date().toDateString())
  }
}

export function compare(property) {
  return function(obj1, obj2) {
    var value1 = obj1[property]
    var value2 = obj2[property]
    return value1 - value2 // 升序
  }
}

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function() {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

  return function(...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在，重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}

/**
 * This is just a simple version of deep copy
 * Has a lot of edge cases bug
 * If you want to use a perfect deep copy, use lodash's _.cloneDeep
 * @param {Object} source
 * @returns {Object}
 */
export function deepClone(source) {
  if (!source && typeof source !== 'object') {
    throw new Error('error arguments', 'deepClone')
  }
  const targetObj = source.constructor === Array ? [] : {}
  Object.keys(source).forEach(keys => {
    if (source[keys] && typeof source[keys] === 'object') {
      targetObj[keys] = deepClone(source[keys])
    } else {
      targetObj[keys] = source[keys]
    }
  })
  return targetObj
}

/**
 * @param {Array} arr
 * @returns {Array}
 */
export function uniqueArr(arr) {
  return Array.from(new Set(arr))
}

/**
 * @returns {string}
 */
export function createUniqueString() {
  const timestamp = +new Date() + ''
  const randomNum = parseInt((1 + Math.random()) * 65536) + ''
  return (+(randomNum + timestamp)).toString(32)
}

/**
 * Check if an element has a class
 * @param {HTMLElement} elm
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass(ele, cls) {
  return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
}

/**
 * Add class to element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function addClass(ele, cls) {
  if (!hasClass(ele, cls)) ele.className += ' ' + cls
}

/**
 * Remove class from element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function removeClass(ele, cls) {
  if (hasClass(ele, cls)) {
    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
    ele.className = ele.className.replace(reg, ' ')
  }
}

// 替换邮箱字符
export function regEmail(email) {
  if (String(email).indexOf('@') > 0) {
    const str = email.split('@')
    let _s = ''
    if (str[0].length > 3) {
      for (var i = 0; i < str[0].length - 3; i++) {
        _s += '*'
      }
    }
    var new_email = str[0].substr(0, 3) + _s + '@' + str[1]
  }
  return new_email
}

// 替换手机字符
export function regMobile(mobile) {
  if (mobile.length > 7) {
    var new_mobile = mobile.substr(0, 3) + '****' + mobile.substr(7)
  }
  return new_mobile
}

// 下载文件
export function downloadFile(obj, name, suffix) {
  const url = window.URL.createObjectURL(new Blob([obj]))
  const link = document.createElement('a')
  link.style.display = 'none'
  link.href = url
  const fileName = parseTime(new Date()) + '-' + name + '.' + suffix
  link.setAttribute('download', fileName)
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

//  判断pc端 true为PC端，false为手机端
export function IsPC() {
  const userAgentInfo = navigator.userAgent
  const Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
  let flag = true
  for (let v = 0; v < Agents.length; v++) {
    if (userAgentInfo.indexOf(Agents[v]) > 0) {
      flag = false
      break
    }
  }
  return flag
}

export const openplatformMap = key => {
  const temp = {
    '-4': '手机',
    '20': '微信',
    '60': '苹果'
  }
  return temp[key] ? temp[key] : '未知'
}

// No: 不禁用  ToDay:今天   ToLeft:过去的时间（不包含当日） ToRight: 未来的时间（不包含当日） ToDayAndLeft: 过去时间（含当日）  ToDayAndRight：未来时间（含当日）
export const DisabledDateTypeMap = {
  No: 'No',
  ToDay: 'ToDay',
  ToLeft: 'ToLeft',
  ToRight: 'ToRight',
  ToDayAndLeft: 'ToDayAndLeft',
  ToDayAndRight: 'ToDayAndRight'
}

/**
 * 日历禁用日期
 * @param {*} time //当前时间
 * @param {*} disabledDateType // 类型
 */
export const disbledDateFun = (time, disabledDateType) => {
  let bool = false
  switch (disabledDateType) {
    case DisabledDateTypeMap.No:
      bool = false
      break
    case DisabledDateTypeMap.ToDay:
      bool = time.getDate() === new Date().getDate()
      break
    case DisabledDateTypeMap.ToLeft:
      bool = time.getTime() < Date.now()
      break
    case DisabledDateTypeMap.ToRight:
      bool = time.getTime() > Date.now()
      break
    case DisabledDateTypeMap.ToDayAndLeft:
      bool = time.getTime() <= Date.now()
      break
    case DisabledDateTypeMap.ToDayAndRight:
      bool = time.getTime() >= Date.now()
      break
    default:
      break
  }
  return bool
}

/**
 * 返回字节长度
 * @param str
 * @returns {number}
 */
export const getByteLen = str => {
  if (!str) {
    return 0
  }
  let len = 0
  for (let i = 0, lens = str.length; i < lens; i++) {
    len += str.charCodeAt(i) > 255 ? 2 : 1
  }
  return len
}

/**
 * 按字节截取字符串
 * @param str 原字符
 * @param length 取的字节长
 * @param flag 是否...
 * @returns {{byteLen: number, len: number, value: string}|string}
 */
export const getStr = (str, length, flag = false) => {
  const strTemp = str
  let objStr = ''
  let num = 0 // 字符串长度
  const byteLen = getByteLen(str) // 字节长度
  if (!str) {
    return ''
  }

  for (let i = 0, lens = strTemp.length; i <= lens; i++) {
    num += strTemp.charCodeAt(i) > 255 ? 2 : 1
    if (num > length) {
      break
    } else {
      objStr = strTemp.substring(0, i + 1)
    }
  }

  if (flag) {
    objStr = byteLen > length ? objStr + '...' : objStr
  }
  // const obj = { len: length, value: objStr, byteLen }
  // console.log(obj);
  return objStr || ''
}

/**
 * 检验时间在某一区间
 * 传入指定时间区间（24小时制，“时钟 : 分钟”）
 * eg： checkAuditTime("12:00", "13:00")
 */
export function checkAuditTime(beginTime, endTime) {
  const nowDate = new Date()
  const beginDate = new Date(nowDate)
  const endDate = new Date(nowDate)

  const beginIndex = beginTime.lastIndexOf(':')
  const beginHour = beginTime.substring(0, beginIndex)
  const beginMinue = beginTime.substring(beginIndex + 1, beginTime.length)
  beginDate.setHours(beginHour, beginMinue, 0, 0)

  const endIndex = endTime.lastIndexOf(':')
  const endHour = endTime.substring(0, endIndex)
  const endMinue = endTime.substring(endIndex + 1, endTime.length)
  endDate.setHours(endHour, endMinue, 0, 0)
  if (nowDate.getTime() - beginDate.getTime() >= 0 && nowDate.getTime() <= endDate.getTime()) {
    return true
  } else {
    return false
  }
}

// ----- 提现 ----

// 资料审核
export const idPicStatusMap = {
  1: '待审核',
  2: '审核通过',
  3: '审核不通过'
}

export const getIdPicStatus = key => {
  return idPicStatusMap[key] ? idPicStatusMap[key] : '未知'
}

export const objTransformArray = (obj, valKey = 'display_name') => {
  const temp = []
  Object.keys(obj).map(key => {
    temp.push({ key, [valKey]: obj[key] })
  })
  return temp
}

/**
 * 数字格式化（逗号，分隔）
 */
export function thousandFormat(num) {
  return num.toString().replace(/\d{1,3}(?=(\d{3})+(?:\.\d*)?$)/g, '$&,')
}

// 提现
export const cashStatusMap = {
  '1': '提现中',
  '2': '提现完成',
  '-1': '提现失败'
}

export const getCashStatus = key => {
  return cashStatusMap[key] ? cashStatusMap[key] : ''
}

// 日期类型映射
export const dateTimeMap = {
  today: 4,
  date: 0,
  week: 1,
  month: 2,
  quarter: 3
}

// 结算状态
export const settlementStatus = {
  '0': '待审批',
  '1': '已完成',
  '2': '未通过',
  '3': '已撤销'
}

// 结算状态样式
export const statusColor = {
  '0': 'statusDots_gray',
  '1': 'statusDots_green',
  '2': 'statusDots_red',
  '3': 'statusDots_black'
}

// 供应商类型
export const supplyType = {
  1: '采购',
  2: '代销',
  3: '采购/代销混合'
}

// 供应商类型
export const invoiceType = {
  0: '无需开票',
  1: '需要开票（待开）',
  2: '需要开票（已开）',
  3: '需要开票'
}

export const supplierTypeOptions = [
  { name: '采购', val: 1 },
  { name: '代销', val: 2 },
  { name: '采购代销混合', val: 3 }
]

// 刮奖状态：0：不可刮，1：可刮，2：已刮，3：已过期
export const scratchStateMap = [
  { key: 0, display_name: '不可刮' },
  { key: 1, display_name: '可刮' },
  { key: 2, display_name: '已刮' },
  { key: 3, display_name: '已过期' }
]

// 订单
/**
 * 检测对象所有属性
 */
export function propertyValidate(O) {
  if (isObject(O)) {
    let flag = false
    for (var key in O) {
      if (O[key]) {
        flag = true
        break
      } else {
        flag = false
      }
    }
    return flag
  } else {
    return false
  }
}

// liveManage

// 转换为小时
export function formatH(ms) {
  if (ms && ms > 0) {
    const _ms = parseInt(ms)
    const _h = _ms / 1000 / 60 / 60
    if (_h < 0.1) {
      return '0.1h'
    }
    return `${(Math.floor(_h * 10) / 10).toFixed(1)}h`
  } else {
    return '0.0h'
  }
}
